#include "StdAfx.h"
CameraDesc::CameraDesc()
{
	Pos=Vec3(0,0,0);
	At=Vec3(0,0,-1);
	Up=Vec3(0,1,0);
	FOV=90;
	FarViewPlane=globals.Graphics.FarViewPlane; 
	NearViewPlane=globals.Graphics.NearViewPlane;
	AspectRatio=1;
}
Camera::Camera(CameraDesc &desc):Actor(desc)
{
	FOV=desc.FOV;
	FarViewPlane=desc.FarViewPlane;
	NearViewPlane=desc.NearViewPlane;
	At=desc.At;
	Up=desc.Up;
	AspectRatio=desc.AspectRatio;
	OrbitRot=Rotator();
	Focus=Vec3();
	bFocus=false;
	FocusDistance=0;
}
Camera::~Camera(void)
{
}
void Camera::UpdateView(int w, int h)
{
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glPushMatrix();
		glLoadIdentity();
		//Set our current view perspective
		//gluPerspective(FOV, (float)w / (float)h, globals.Graphics.NearViewPlane, globals.Graphics.FarViewPlane);
		AspectRatio=(float)w/(float)h;
	//Model view
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
	glPushMatrix();
		glLoadIdentity();
		Vec3 pos=GetPos();
		//gluLookAt(GetPos().x, GetPos().y, GetPos().z, GetAt().x, GetAt().y, GetAt().z, GetUp().x, GetUp().y, GetUp().z);
	_err("Camera Update View Failed:");
}
void Camera::ResetView()
{
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glPushMatrix();
		glLoadIdentity();
	//Model view
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
	glPushMatrix();
		glLoadIdentity();
}
void Camera::Move(Vec3 v)
{
	At+=v;
	Pos+=v;
}
Vec3 Camera::GetPos()
{
	if(bFocus)
	{
		Vec3 dir=Vec3(0,0,1);
		OrbitRot.Rotate(dir);
		return Focus+dir*FocusDistance;
	}
	else return Pos;
}
Vec3 Camera::GetAt()
{
	if(bFocus)
	{
		Vec3 dir=Focus-GetPos();
		Rot.Rotate(dir);
		return GetPos()+dir;;
	}
	else return At;
} 
Vec3 Camera::GetLookDir()
{
	return GetAt()-GetPos();
}
Vec3 Camera::GetStrafeDir()
{
	Vec3 look=GetLookDir(), up=GetUp();
	Vec3 dir=look.cross(up);
	return dir;
}
Vec3 Camera::GetUp()
{
	if(bFocus)
	{
		Vec3 up=Vec3(0,1,0);
		OrbitRot.Rotate(up);
		Rot.Rotate(up);
		return up;
	}
	else return Up;
}
void Camera::Rotate(Rotator rot)
{
	Vec3 dir=GetLookDir();
	rot.Rotate(dir);
	rot.Rotate(Up);
	At=Pos+dir;
}
void Camera::Orbit(Rotator rot)
{
	Vec3 rdir=Pos-At;
	rot.Rotate(rdir);
	Pos=At+rdir;
}
void Camera::SetLookDir(Vec3 dir)
{
	At=Pos+dir;
}
void Camera::ResetLook()
{
	SetLookDir(Vec3(0,0,-1));
	Up=Vec3(0,1,0);
}
void Camera::SetUp(Vec3 v)
{
	Up=v;
}
